﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using eTerm.NetSocket;
using System.Net.Sockets;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;
namespace WebeTerm.PlugIns
{
    /// <summary>
    /// 插件基类
    /// </summary>
    /// <typeparam name="T">分析结果数据类型</typeparam>
    public abstract class BaseTermPlugIn :BasePlugIn, IPlugIn
    {

        /// <summary>
        /// 默认构造函数
        /// </summary>
        protected BaseTermPlugIn()
        {
            UnPacketResultWorks = new List<UnPacketStreamWorker>();
        }
         
        /// <summary>
        /// eTerm配置对像
        /// </summary>
        public BaseTermSocket eTermSession { get;private set; }

        /// <summary>
        /// 配置登录成功事件通知
        /// </summary>
        public event EventHandler OneTermValidated;


        /// <summary>
        /// 得到插件结果事件通知
        /// </summary>
        public event EventHandler<eTermPlugInEventArgs> OnUnPackResult;

        /// <summary>
        /// 触发结果通知事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void FireOnUnPackResult(eTermPlugInEventArgs e) {
            if (OnUnPackResult != null)
                OnUnPackResult(this, e);
        }

        /// <summary>
        /// 结果处理办法集合
        /// </summary>
        public List<UnPacketStreamWorker> UnPacketResultWorks { get; set; }


        /// <summary>
        /// 配置断开事件通知
        /// </summary>
        public event EventHandler OneTermDisconnected;


        /// <summary>
        /// 指令结果事件通知
        /// </summary>
        public event EventHandler<SocketPacketEventArgs> OneTermReadPacket;


        /// <summary>
        /// 数据包接收事件通知
        /// </summary>
        /// <param name="CmdStr"></param>
        /// <param name="Result"></param>
        protected abstract void OnReadPacket(string CmdStr, string Result);

        /// <summary>
        /// 插件主执行方法.
        /// </summary>
        public override void Execute()
        {
            Connect(Config.eTermSessionType, Config.eTermAddress, Config.eTermPort, Config.userName, Config.Password, Config.siText, Config.RID, Config.SID);
        }

        /// <summary>
        /// eTerm配置信息.
        /// </summary>
        /// <value>The configuration.</value>
        public virtual eTermConfig Config {protected get; set; }

        /// <summary>
        /// 连接配置
        /// </summary>
        /// <param name="eTermType">配置类型</param>
        /// <param name="address">服务器地址</param>
        /// <param name="port">配置端口</param>
        /// <param name="userName">用户</param>
        /// <param name="password">密码</param>
        /// <param name="rid">RID</param>
        /// <param name="sid">SID</param>
        protected virtual void Connect(SocketConnectType eTermType, string address, int port, string userName, string password,string siText = @"SI", byte rid = 0x00, byte sid = 0x00)
        {
            switch (eTermType) { 
                case SocketConnectType.User443:
                    eTermSession = new eTerm443Socket(address, port, userName, password, rid, sid);
                    break;
                default:
                    eTermSession = new eTerm350Socket(address, port, userName, password, rid, sid);
                    break;
            }

            eTermSession.OnDisconnecting += (o, e) => {
                if (OneTermDisconnected != null)
                    OneTermDisconnected(this, e);
            };

            eTermSession.OnValidated += (o, e) => {
                if (OneTermValidated != null)
                    OneTermValidated(this, e);
            };
            eTermSession.AllowReconnect = false;
            eTermSession.SurplusCmdCount = int.MaxValue;
            eTermSession.SiText = siText;
            eTermSession.OnReadPacket += (o, e) => {
                BaseTermSocket eSession = (o as BaseTermSocket);
                byte[] buffer = eSession.Outpacket.GetStream();
                if (buffer[8] == eSession.RID && buffer[9] == eSession.SID)
                {
                    SocketPacketEventArgs e1 = new SocketPacketEventArgs();
                    string cmd = Encoding.GetEncoding(@"gb2312").GetString(eSession.Depacket(buffer));
                    string result = Encoding.GetEncoding(@"gb2312").GetString(eSession.Depacket(eSession.Inpacket.GetStream(), 5));
                    e1.PacketResult = result;
                    e1.PacketName = cmd;
                    if (OneTermReadPacket != null)
                        OneTermReadPacket(this, e1);
                    OnReadPacket(cmd, result);
                }
            };

            eTermSession.Connect();
        }

        /// <summary>
        /// 发送eTerm指令
        /// </summary>
        /// <param name="outPacket"></param>
        protected virtual void SendStream(string outPacket) {
            Thread.Sleep(1000);
            eTermSession.SendStream(outPacket);
        }

        /// <summary>
        /// 发送eTerm指令
        /// </summary>
        /// <param name="outPacket"></param>
        public virtual void SendStream(byte[] outPacket)
        {
            Thread.Sleep(1000);
            eTermSession.SendStream(outPacket);
        }

        /// <summary>
        /// 关闭配置连接
        /// </summary>
        protected virtual void Disconnect() {
            eTermSession.Close();
        }

    }
}
